Skip to main content

Fail2Ban

Fail2Ban is a log-based intrusion prevention tool that monitors service logs for suspicious activity (such as repeated authentication failures) and applies temporary bans using the host firewall. It is commonly used to reduce brute-force attempts against SSH and other internet-exposed services on Linux servers.

Background and history

As brute-force attacks became routine on public servers, administrators needed a lightweight way to react automatically to repeated failures without deploying full IDS/IPS systems. Fail2Ban emerged as a pragmatic approach: watch logs for known failure patterns and apply short-lived firewall blocks to slow attackers and reduce noise.

Fail2Ban is widely deployed on VPS and cloud servers, particularly for SSH hardening and basic protection for common services. It is often paired with a baseline host firewall policy (UFW, iptables/nftables, or firewalld) and external perimeter controls (cloud security groups, reverse proxies).

Maintained by

  • Maintained by the Fail2Ban community.

Best When to Use

  • You need automated mitigation for brute-force attempts against SSH and other log-producing services.
  • You run a small-to-medium fleet where host-local protection is acceptable.
  • You already have a host firewall enabled and want dynamic temporary bans.
  • You want a low-overhead complement to upstream controls (cloud security groups, CDN/WAF).

Not Suitable When

  • You need deep packet inspection, protocol analysis, or payload signatures (use IDS/IPS tooling).
  • You cannot rely on consistent log output (custom services without reliable logs).
  • You require centralized enforcement and correlation across many hosts as the primary control (use SIEM/EDR + centralized policy).
  • You expect attackers to rotate IPs rapidly and need upstream rate limiting or bot mitigation.

Compatibility Notes

  • Works best on distributions with systemd and consistent logging (journald and/or traditional log files).

  • SSH logs differ by distro and configuration:

    • Debian/Ubuntu commonly use /var/log/auth.log
    • RHEL/Fedora commonly use /var/log/secure
  • Firewall backend depends on system configuration:

    • UFW (Ubuntu-friendly)
    • iptables/nftables (direct)
    • firewalld (common on RHEL/Fedora)
  • Containers typically inherit host networking and firewalling behavior; Fail2Ban is usually configured on the host.

Lockout risk

A misconfigured jail can ban your own IP or block SSH unexpectedly. Always confirm SSH access rules before enabling bans, keep console/serial recovery access available, and start with conservative thresholds.

Concepts and How It Works

Fail2Ban has three core building blocks:

ComponentPurpose
FiltersRegular expressions that match suspicious log entries
JailsDefine what to monitor and how to ban (thresholds, times, actions)
ActionsThe ban mechanism (firewall rule insertion, notifications, etc.)

Prerequisites

  • Root or sudo privileges
  • A supported firewall backend enabled (UFW, iptables/nftables, or firewalld)
  • Reliable logs for the services you want to protect (SSH, web auth, mail, etc.)
  • Log rotation configured and disk space monitored

Installation

Debian/Ubuntu

sudo apt update
sudo apt install fail2ban

RHEL/CentOS Stream/Fedora

sudo dnf install fail2ban

Alpine

sudo apk add fail2ban

Safe Validation Before Changes

Start with read-only checks to confirm Fail2Ban is installed and can see logs.

Check service status

sudo systemctl status fail2ban --no-pager

Check overall Fail2Ban status

sudo fail2ban-client status

View recent Fail2Ban logs

sudo tail -n 200 /var/log/fail2ban.log 2>/dev/null || true
sudo journalctl -u fail2ban -n 200 --no-pager

Configuration Files and Layout

File/DirectoryTypical PathPurpose
Main config/etc/fail2ban/fail2ban.confCore daemon settings (rarely edited directly)
Default jails/etc/fail2ban/jail.confVendor defaults (do not edit directly)
Local overrides/etc/fail2ban/jail.local or /etc/fail2ban/jail.d/*.localYour configuration (recommended)
Filters/etc/fail2ban/filter.d/Regex filters that detect patterns
Log file/var/log/fail2ban.logFail2Ban activity log (if enabled)
Configuration best practice

Avoid editing jail.conf. Use jail.local or files in jail.d/ so updates do not overwrite your settings.

Create a Baseline SSH Jail

Use a dedicated override file, which is easier to manage than a large jail.local.

Debian/Ubuntu example

Create /etc/fail2ban/jail.d/sshd.local:

[sshd]
enabled = true
port = ssh
logpath = /var/log/auth.log
maxretry = 5
findtime = 10m
bantime = 1h
backend = systemd

Apply changes:

sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

RHEL/Fedora example

Create /etc/fail2ban/jail.d/sshd.local:

[sshd]
enabled = true
port = ssh
logpath = /var/log/secure
maxretry = 5
findtime = 10m
bantime = 1h
backend = systemd

Apply changes:

sudo systemctl restart fail2ban
sudo fail2ban-client status sshd
Start conservative

If your server is frequently accessed from variable IPs (home ISP, mobile), use a higher maxretry and shorter bantime initially to reduce accidental lockouts.

Firewall Backend Notes

Fail2Ban can apply bans using different actions depending on your firewall.

Common choices:

  • UFW systems often use banaction = ufw
  • iptables systems use iptables-multiport
  • nftables systems use nftables-multiport
  • firewalld systems use firewallcmd-ipset

You can set the default ban action under [DEFAULT] in jail.local or a file in jail.d/.

Example snippet (UFW):

[DEFAULT]
banaction = ufw

Example snippet (nftables):

[DEFAULT]
banaction = nftables-multiport
Action availability

Not all actions are packaged the same way across distributions. Confirm available actions in /etc/fail2ban/action.d/ before selecting a custom banaction.

Common Commands

Service control

sudo systemctl start fail2ban
sudo systemctl stop fail2ban
sudo systemctl restart fail2ban
sudo systemctl reload fail2ban

Status and jail inspection

sudo fail2ban-client status
sudo fail2ban-client status sshd

Manually ban and unban

sudo fail2ban-client set sshd banip 203.0.113.10
sudo fail2ban-client set sshd unbanip 203.0.113.10
Correction

Some references use fail2ban-client unban <IP>, but the reliable syntax is fail2ban-client set <jail> unbanip <IP>.

Practical Use Cases

Reduce SSH brute force noise

  • Enable the sshd jail
  • Ensure SSH is restricted at the firewall (allow only required sources if possible)
  • Use strong authentication (keys) and disable password auth when feasible

Protect a web admin endpoint (example pattern)

For web apps that log authentication failures to a file, Fail2Ban can monitor that log with a custom filter and jail. Ensure:

  • Logs are consistent and include source IPs
  • The filter is tested before enabling bans

Safe workflow:

  1. Create filter in /etc/fail2ban/filter.d/
  2. Run Fail2Ban in monitoring mode (jail enabled with higher thresholds)
  3. Review bans and false positives
  4. Tighten thresholds gradually

Troubleshooting

SymptomLikely CauseSafe ChecksFix
--
Jail shows 0 failures despite attacksWrong logpath or backendfail2ban-client status <jail>, check logs existFix logpath, set backend = systemd if using journald
You get banned unexpectedlyThreshold too aggressive or shared IPfail2ban-client status <jail>Increase maxretry, reduce bantime, whitelist trusted IPs
Bans do not block trafficWrong banaction for firewallCheck /etc/fail2ban/action.d/, firewall statusSet correct banaction, restart Fail2Ban
High CPU / frequent restartsLog volume too high or regex too broadReview Fail2Ban logsNarrow filters, reduce monitored log volume
SSH access lostYour IP banned or firewall rules changedUse console accessUnban your IP, disable jail temporarily, verify SSH allow rules

Whitelisting Trusted IPs

Whitelisting prevents trusted sources from being banned.

Add to a local override (for example /etc/fail2ban/jail.d/local-defaults.local):

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.10

Apply:

sudo systemctl restart fail2ban
Whitelist carefully

Whitelisting broad ranges (such as office networks or VPN subnets) reduces protection. Prefer the smallest set of trusted IPs that matches operational needs.

Security Notes

  • Fail2Ban is a mitigation layer, not a primary firewall policy.
  • Prefer SSH keys over passwords and disable password authentication when possible.
  • Use upstream controls (cloud security groups, reverse proxies, WAF/CDN) to reduce attack surface.
  • Monitor ban activity and tune thresholds based on real traffic patterns.

Emergency Recovery

If you are locked out of SSH, use out-of-band access (cloud console/serial/KVM) to recover.

Temporarily stop Fail2Ban

sudo systemctl stop fail2ban

Unban your IP (after regaining access)

sudo fail2ban-client status
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip <your-ip>

If the firewall is the cause

Verify firewall rules and restore SSH access safely before re-enabling bans. Use read-only inspection first:

sudo ufw status verbose 2>/dev/null || true
sudo iptables -S 2>/dev/null || true
sudo nft list ruleset 2>/dev/null || true
sudo firewall-cmd --state 2>/dev/null || true

Quick Reference Cheat Sheet

GoalCommand
---
Overall statussudo fail2ban-client status
Jail statussudo fail2ban-client status sshd
Restart servicesudo systemctl restart fail2ban
View logs (file)sudo tail -n 200 /var/log/fail2ban.log
View logs (journal)sudo journalctl -u fail2ban -n 200 --no-pager
Ban IPsudo fail2ban-client set sshd banip <ip>
Unban IPsudo fail2ban-client set sshd unbanip <ip>